package com.mingliqiye.minecraft.enchantment.conflict.neoforge.network;

import com.mingliqiye.minecraft.enchantment.conflict.common.ConfigManager;
import com.mingliqiye.minecraft.enchantment.conflict.common.ConfigPair;
import com.mingliqiye.minecraft.enchantment.conflict.common.MinecraftMod;
import com.mingliqiye.minecraft.enchantment.conflict.neoforge.NeoForgeMod;
import com.mojang.logging.LogUtils;
import java.util.Map;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.neoforge.event.entity.player.PlayerEvent;
import net.neoforged.neoforge.network.PacketDistributor;
import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent;
import net.neoforged.neoforge.network.registration.PayloadRegistrar;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;

public record ConfigPayload(Map<String, ConfigPair> data) implements CustomPacketPayload {
    private static final Logger LOGGER = LogUtils.getLogger();
    public static final CustomPacketPayload.Type<ConfigPayload> TYPE = new CustomPacketPayload.Type<>(
        ResourceLocation.tryBuild(MinecraftMod.MOD_ID, "config_packet")
    );

    public static final StreamCodec<FriendlyByteBuf, ConfigPayload> STREAM_CODEC = StreamCodec.composite(
        ByteBufCodecs.STRING_UTF8,
        (p) -> ConfigManager.toyaml(p.data()),
        (s) -> new ConfigPayload(ConfigManager.fromyaml(s))
    );

    public static void sendConfig(ServerPlayer player) {
        var conf = NeoForgeMod.CONFIGMANAGER.getConfig();
        LOGGER.info("Send Server Config {} to {} data={}", MinecraftMod.MOD_ID, player.getName().getString(), conf);
        PacketDistributor.sendToPlayer(player, new ConfigPayload(conf));
    }

    public static void sendToAllPlayers(Map<String, ConfigPair> conf) {
        LOGGER.info("Send Server Config {} to @a data={}", MinecraftMod.MOD_ID, conf);
        PacketDistributor.sendToAllPlayers(new ConfigPayload(conf));
    }

    @SubscribeEvent
    public static void register(final RegisterPayloadHandlersEvent event) {
        PayloadRegistrar registrar = event.registrar(MinecraftMod.MOD_ID).versioned("2.0");
        registrar.playToClient(ConfigPayload.TYPE, ConfigPayload.STREAM_CODEC, (payload, context) -> {
            context.enqueueWork(() -> {
                NeoForgeMod.CONFIGMANAGER.setConfig(payload.data());
                LOGGER.info("Load Server Config {} data={}", MinecraftMod.MOD_ID, ConfigManager.tojson(payload.data()));
            });
        });
    }

    @Override
    @NotNull
    public CustomPacketPayload.Type<? extends CustomPacketPayload> type() {
        return TYPE;
    }
}
